package com.ailot.cloud.upms.api.service.impl;

import cn.hutool.core.util.StrUtil;
import com.ailot.cloud.base.common.constants.CommonConstant;
import com.ailot.cloud.upms.api.datasource.DataSourceConstant;
import com.ailot.cloud.upms.api.mapper.SysDatasourceMapper;
import com.ailot.cloud.upms.api.mapper.SysDictValueMapper;
import com.ailot.cloud.upms.api.mapper.SysGenMapper;
import com.ailot.cloud.upms.api.service.SysGenService;
import com.ailot.cloud.upms.common.entity.*;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import org.assertj.core.util.Lists;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author : litao
 * @create 2023/12/6 14:50
 */
@Service
@AllArgsConstructor
public class SysGenServiceImpl implements SysGenService {

    private final SysDatasourceMapper sysDatasourceMapper;

    private final SysGenMapper sysGenMapper;

    private final SysDictValueMapper sysDictValueMapper;

    //模板名称集合
    private final static List<String> templates = Lists.newArrayList("entity", "mapper", "service", "serviceImpl", "controller", "index_arco", "form_arco", "api_arco");

    @Override
    public List<SysTable> list(String tableName, String datasourceId) {
        String dbName = CommonConstant.UPMS_DATABASE;
        if (StrUtil.isNotBlank(datasourceId)) {
            SysDatasource datasource = sysDatasourceMapper.selectById(datasourceId);
            dbName = datasource.getName();
            DynamicDataSourceContextHolder.push(dbName);
        }
        List<SysTable> tableList = sysGenMapper.tableList(dbName, tableName);
        DynamicDataSourceContextHolder.push(DataSourceConstant.DB_DEFAULT);
        return tableList;
    }

    @Override
    public Map<String, String> view(SysGen sysGen) {
        String dbName = CommonConstant.UPMS_DATABASE;
        if (StrUtil.isNotBlank(sysGen.getDatasourceId())) {
            SysDatasource datasource = sysDatasourceMapper.selectById(sysGen.getDatasourceId());
            dbName = datasource.getName();
            DynamicDataSourceContextHolder.push(dbName);
        }
        //查询表信息
        SysTable table = sysGenMapper.table(dbName, sysGen.getTableName());
        //查询列信息
        List<SysColumn> columns = sysGenMapper.columnList(dbName, sysGen.getTableName());
        DynamicDataSourceContextHolder.push(DataSourceConstant.DB_DEFAULT);
        //生成代码
        Map<String, String> codeMap = this.generatorCode(sysGen, table, columns);

        return codeMap;
    }

    @Override
    public Map<String, String> generatorCode(SysGen sysGen, SysTable sysTable, List<SysColumn> sysColumns) {
        Map<String, String> fieldMap = this.initField();
        // 驼峰转换
        String tableName1 = StrUtil.toCamelCase(sysTable.getTableName());
        sysTable.setVarTableName(tableName1);
        //首字母大写
        String tableName2 = StrUtil.upperFirst(tableName1);
        sysTable.setCamelTableName(tableName2);
        //列属性处理
        sysColumns.forEach(item -> {
            String columnName = StrUtil.toCamelCase(item.getColumnName());
            item.setCamelColumnName(columnName);
            //数据库类型转换为Java类型
            item.setAttrType(fieldMap.get(item.getDataType()));
            //主键判断
            if (DataSourceConstant.PRI.equalsIgnoreCase(item.getColumnKey())) {
                sysTable.setPk(item);
            }
        });
        sysTable.setSysColumns(sysColumns);
        //模板引擎
        TemplateEngine engine = new TemplateEngine();
        //读取磁盘中的模板文件
        ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
        //指定路径
        resolver.setPrefix("templates/");
        //后缀
        resolver.setSuffix(".th");
        //设置模板模式、默认是HTML
        resolver.setTemplateMode("TEXT");
        //设置引擎使用 resolve
        engine.setTemplateResolver(resolver);
        //准备数据 使用context
        Context context = new Context();
        //模板数据组装
        Map<String, Object> map = Maps.newHashMap();
        map.put("packageName", sysGen.getPackageName());
        map.put("moduleName", sysGen.getModuleName());
        map.put("author", sysGen.getAuthor());
        map.put("remark", sysGen.getRemark());
        map.put("tableName", sysTable.getTableName());
        map.put("upperCaseTableName", sysTable.getTableName().toUpperCase());
        map.put("tableComment", sysTable.getTableComment());
        map.put("camelTableName", sysTable.getCamelTableName());
        map.put("columns", sysTable.getSysColumns());
        map.put("pk", sysTable.getPk());
        map.put("varTableName", sysTable.getVarTableName());
        map.put("pathName", sysTable.getVarTableName().toLowerCase());
        map.put("dateTime", LocalDate.now());
        context.setVariables(map);
        Map<String, String> dataMap = Maps.newHashMap();
        for (String template : templates) {
            String process = engine.process(template, context);
            dataMap.put(template, process);
        }
        return dataMap;
    }

    private Map<String, String> initField() {
        List<SysDictValue> sysDictValueList = sysDictValueMapper.selectList((Wrappers
                .<SysDictValue>lambdaQuery()
                .eq(SysDictValue::getType, DataSourceConstant.FIELD_TYPE)));
        Map<String, String> map = sysDictValueList.stream().collect(Collectors.toMap(SysDictValue::getLabel, SysDictValue::getValue));
        return map;
    }


}
